﻿#include "Mainwindow.h"

#include <QPolygon>
#include <QPushButton>
#include <QGraphicsTextItem>

/*
* 图形视图框架：
	图形视图提供了一个界面，用于管理大量定制的2D图形项并与之交互，还提供了一个视图小部件，用于可视化这些项，支持缩放和旋转。
	该框架包括一个事件传播体系结构，允许对场景中的项目进行精确的双精度交互功能。项目可以处理按键事件、鼠标按下、移动、释放和双击事件，还可以跟踪鼠标移动。
	Graphics View使用BSP(二进制空间分区)树来提供非常快速的项目发现，因此，它可以实时可视化大型场景，即使有数百万个项目。

	1.场景(Scene)	
		QGraphicsScene提供了图形视图场景。本场景主要职责如下:
			为管理大量Items提供了一个快速的界面
			将事件传播到每个item
			管理Items状态，例如选择和焦点处理
			提供未转换的呈现功能；主要用于印刷
		场景充当QGraphicsItem对象的容器。通过调用QGraphicsScene::addItem()将item添加到场景中，然后通过调通过调用众多item查找函数来检索。
		QGraphicsScene的事件传播架构安排场景事件以传递到项目，并且还管理项目之间的传播。如果场景在某个位置接收到一个鼠标按下事件，
			场景将该事件传递给位于该位置的任何项目。
		QGraphicsScene还管理某些项目状态，比如项目选择和焦点。你可以通过调用QGraphicsScene::setSelectionArea()来选择场景中的项目，
			传递一个任意形状。这个功能也被用作在QGraphicsView中选择橡皮筋的基础。调用QGraphicsScene::selectedItems()获取当前所有选中项的列表。
			QGraphicsScene处理的另一个状态是项目是否有键盘输入焦点。
			你可以通过调用QGraphicsScene::setFocusItem()或QGraphicsItem::setFocus()来设置一个项目的焦点，
			或者通过调用QGraphicsScene::focusItem()来获取当前的焦点项目。
		最后，QGraphicsScene允许你通过QGraphicsScene::render()函数将部分场景渲染到绘制设备中。您可以在本文档后面的打印部分阅读更多相关内容。

	2.视图（View）
		QGraphicsView提供了视图小部件，它可视化了场景的内容。您可以将多个视图附加到同一个场景，从而为相同的数据集提供多个视口。视图小部件是一个滚动区域，
		并提供滚动条用于在大型场景中导航。

	3.图形项（Item）
		QGraphicsItem是场景中图形项的基类。图形视图为典型形状提供了几个标准项，
		例如矩形(QGraphicsRectItem)、椭圆(QGraphicsEllipseItem)和文本项(QGraphicsTextItem)，但最强大的QGraphicsItem特性是在编写自定义项时可用的。
		除此之外，QGraphicsItem支持以下特性:
			鼠标按下、移动、释放和双击事件，以及鼠标悬停事件、滚轮事件和上下文菜单事件。
			键盘输入焦点和按键事件
			拖放
			通过父子关系和QGraphicsItemGroup进行分组
			碰撞检测
		item存在于本地坐标系统中，像QGraphicsView一样，它还提供了许多函数来映射项目和场景之间的坐标，以及项与项之间的坐标。同样，像QGraphicsView一样，
			它可以使用矩阵:QGraphicsItem::transform()转换其坐标系统。这对于旋转和缩放单个项目非常有用。
		项可以包含其他项(子项)。父项的转换由其所有子项继承。然而，不管一个项的累积转换如何，
			它的所有函数(例如，QGraphicsItem::contains()， QGraphicsItem::boundingRect()， QGraphicsItem::collidesWith())仍然在局部坐标中操作。
		QGraphicsItem通过QGraphicsItem::shape()函数和QGraphicsItem::collidesWith()支持碰撞检测，这两个函数都是虚函数。
			通过从QGraphicsItem::shape()返回物体的形状作为局部坐标QPainterPath, QGraphicsItem将为你处理所有的碰撞检测。
			但是，如果你想提供自己的碰撞检测，你可以重新实现QGraphicsItem::collidesWith()。
*/


Mainwindow::Mainwindow(QWidget* parent)
	:QWidget(parent)
{
	//标题重命名：
	this->setWindowTitle("qt");

	this->resize(640, 480);


	init();
}

Mainwindow::~Mainwindow()
{
	delete m_view;
	delete m_scene;

}

void Mainwindow::init()
{
	//布局初始化：
	layoutinit();
}


void Mainwindow::layoutinit()
{
	//创建场景：
	m_scene = new QGraphicsScene(0, 0, 640, 480);

	//创建视图：		添加场景有两个方法：1.通过构造函数添加场景；2.通过	m_view->setScene(m_scene);添加场景：
	m_view = new QGraphicsView(m_scene);
		//m_view->setScene(m_scene);

	//显示view：
	m_view->show();


	//视图有三层：1.最底层-背景；2. 中间层-显示图元；3.最上层-前景；



	/*
		设置图形界面	有两种，一是设置视图view，二是设置场景scene；	这两种设置有区别，
		通过视图view设置只是显示被设置的，如果有两个以上的视图，那么其他的视图就为空;
		通过场景scene设置		那么无论有多少个视图	都能显示;
	*/
	//为了方便展示	先		再添加一个视图：
		//auto view = new QGraphicsView(m_scene);
		//view->setScene(m_scene);
		//view->show();
#if 0			//通过view来设置；
	//通过view设置背景颜色：
	//m_view->setBackgroundBrush(Qt::GlobalColor::green);
	m_view->setBackgroundBrush(QPixmap("./assets/image/tu1.png"));

	//设置前景颜色：
	m_view->setForegroundBrush(QColor(128, 128, 128,50)/* 灰色，透明度50 */);
#else			//通过scene来设置；
	//设置背景：
	m_scene->setBackgroundBrush(QPixmap("./assets/image/tu1.png"));

	//设置前景：
	m_scene->setForegroundBrush(QColor(128, 128, 128, 50)/* 灰色，透明度50 */);

#endif


	//给场景添加图元：	（图形元素项 item）
	m_scene->addLine(0, 300, 640, 300,QPen(QColor(255,255,255),4/*设置字体宽度*/));
	//添加多边形：
	QPolygonF triangle;
	triangle << QPointF(m_scene->width() / 2, 0) << QPointF(m_scene->width(), m_scene->height()) << QPointF(0, m_scene->height());
	m_scene->addPolygon(triangle);
	//添加图片：
	m_scene->addPixmap(QPixmap("./assets/image/tu1.png").scaled(150, 150, Qt::KeepAspectRatio/* 保持宽高比 */)/*缩放*/);
	//添加文字：
	m_scene->addSimpleText("5条悟变成2.5条悟喽");
	//添加widget：
	m_scene->addWidget(new QPushButton("clicked"));

	//自己创建图元然后添加进去：
	auto textItem = m_scene->addText("五条悟能不能复活？");
	textItem->setPos(460, 20);				//设置位置；
	textItem->setFont(QFont("微软雅黑", 15));		//设置字体
	textItem->setHtml("<h1 style=\"color:'red';\">宿傩</h1>");	//还可以通过html设置；




}
